package com.example.wechat.service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.project.entity.User;
import com.example.project.service.CommonService;
import com.example.project.utils.PageUtils;
import com.example.wechat.domain.MessageSendResult;
import com.example.wechat.domain.PageInfo;
import com.example.wechat.mapper.WeChatMapper;
import com.example.wechat.mapper.WechatConversationMapper;
import com.example.wechat.mapper.WechatConversationMemberMapper;
import com.example.wechat.mapper.WechatMessageMapper;
import com.example.wechat.mapper.WechatUnreadMessageMapper;
import com.example.wechat.model.WechatConversation;
import com.example.wechat.model.WechatConversationMember;
import com.example.wechat.model.WechatMessage;
import com.example.wechat.model.WechatUnreadMessage;

import cn.hutool.core.builder.GenericBuilder;

@Service
public class WechatMessageService {

	private static final Logger log = LoggerFactory.getLogger(WechatMessageService.class);

	@Autowired
	private CommonService commonService;

	@Autowired
	private WebSocketService webSocketService;

	@Autowired
	private WeChatMapper messageRepository;

	@Autowired
	private WechatMessageMapper messageMapper;

	@Autowired
	private WechatConversationMapper conversationMapper;

	@Autowired
	private WechatConversationMemberMapper conversationMemberMapper;

	@Autowired
	private WechatUnreadMessageMapper unreadMessageMapper;

	// 内存缓存，存储用户会话的最新状态（可选优化）
	private final Map<String, ConversationCache> conversationCache = new ConcurrentHashMap<>();

	public Page<WechatMessage> getMessagesWithPagination(int pageNum, int pageSize, String from, String to) {
		Page<WechatMessage> page = new Page<>(pageNum, pageSize);
		return messageRepository.findMessagesWithPagination(page, from, to);
	}

	public List<WechatMessage> findMessagesByTimeRange(String from, String to, String startTime, String endTime) {
		return messageRepository.findByFromOrToAndTimestampBetween(from, to, startTime, endTime);
	}

	public Map<String, Object> getMessageStatistics(String user, String otherUser) {
		long total = messageRepository.countByUser(user);
		long unread = messageRepository.countUnreadByUser(user);
		long withUser = otherUser != null ? messageRepository.countByFromAndTo(user, otherUser) : 0;

		return Map.of("totalMessages", total, "unreadMessages", unread, "messagesWithUser", withUser);
	}

	public long countUnreadMessages(String user, String from) {
		if (from != null) {
			return messageRepository.countUnreadByFromAndTo(from, user);
		}
		return messageRepository.countUnreadByTo(user);
	}

	public List<WechatMessage> queryByConversationId(Long conversationId) {
		// TODO Auto-generated method stub
		List<WechatMessage> messageList = messageMapper.queryByConversationId(conversationId, 10);
		return messageList;
	}

	/**
	 * 发送消息核心方法
	 */
	public MessageSendResult sendMessage(String conversationId, String senderId, String content, Integer messageType,
			Map<String, Object> additionalData) {
		try {
			// 1. 验证会话和发送者权限
			WechatConversation conversation = validateConversationAndSender(Long.parseLong(conversationId),
					Long.parseLong(senderId));

			// 2. 创建消息实体
			WechatMessage message = createMessageEntity(Long.parseLong(conversationId), Long.parseLong(senderId),
					content, messageType, additionalData);

			// 3. 保存消息到数据库
			messageRepository.insertWechatMessage(message);

			// 4. 更新会话的最后消息信息
			updateConversationLastMessage(conversation, message);

			// 5. 处理未读消息计数
			List<Long> receivers = updateUnreadCounts(Long.parseLong(conversationId), senderId, message);

			// 6. 准备推送数据
			Map<String, Object> pushData = preparePushData(message, conversation, senderId);

			log.info("消息发送成功: messageId={}, conversationId={}, senderId={}", message.getId(), conversationId, senderId);

			return GenericBuilder.of(MessageSendResult::new)
					.with(MessageSendResult::setMessageId, String.valueOf(message.getId()))
					.with(MessageSendResult::setConversationId, conversationId)
					.with(MessageSendResult::setSenderId, senderId).with(MessageSendResult::setContent, content)
					.with(MessageSendResult::setMessageType, String.valueOf(messageType))
					.with(MessageSendResult::setReceivers, receivers)
					.with(MessageSendResult::setSendTime, message.getSendTime())
					.with(MessageSendResult::setPushData, pushData).with(MessageSendResult::setSuccess, true).build();

		} catch (Exception e) {
			log.error("发送消息失败: conversationId={}, senderId={}, error={}", conversationId, senderId, e.getMessage(), e);
			return GenericBuilder.of(MessageSendResult::new).with(MessageSendResult::setErrorMessage, e.getMessage())
					.with(MessageSendResult::setSuccess, false).build();
		}
	}

	/**
	 * 验证会话和发送者权限
	 */
	private WechatConversation validateConversationAndSender(Long conversationId, Long senderId) {
		// 查找会话
		WechatConversation conversation = conversationMapper.findById(conversationId)
				.orElseThrow(() -> new RuntimeException("会话不存在: " + conversationId));

		// 验证发送者是否是会话成员
		boolean isMember = isMenber(conversationId, senderId);
		if (!isMember) {
			throw new RuntimeException("用户不是会话成员，无权发送消息");
		}

		// 验证会话是否已被删除
		if (conversation.getDelFlag() == 1) {
			throw new RuntimeException("会话已被删除");
		}

		return conversation;
	}

	private boolean isMenber(Long conversationId, Long senderId) {
		Integer isMember = conversationMemberMapper.existsByConversationIdAndUserId(conversationId, senderId);
		return isMember != 0;
	}

	/**
	 * 创建消息实体
	 */
	private WechatMessage createMessageEntity(Long conversationId, Long fromUser, String content, Integer messageType,
			Map<String, Object> additionalData) {
		WechatMessage message = new WechatMessage();
		message.setConversationId(conversationId);
		message.setFromUser(fromUser);
		message.setContent(content);
		message.setMessageType(messageType != null ? messageType : 1);
		message.setSendTime(LocalDateTime.now());
		message.setStatus(1); // 发送成功

		// 设置扩展数据
//		if (additionalData != null) {
//			message.setAdditionalData(additionalData);
//		}

		return message;
	}

	/**
	 * 更新会话的最后消息信息
	 */
	private void updateConversationLastMessage(WechatConversation conversation, WechatMessage message) {
		conversation.setLastMessageId(message.getId());
		conversation.setLastMessageContent(truncateContent(message.getContent()));
		conversation.setLastMessageTime(message.getSendTime());
		conversation.setUpdateTime(LocalDateTime.now());

		conversationMapper.save(conversation);

		// 更新缓存
		updateConversationCache(conversation);
	}

	/**
	 * 处理未读消息计数
	 */
	private List<Long> updateUnreadCounts(Long conversationId, String senderId, WechatMessage message) {
		// 获取会话中的所有成员（除了发送者）
		List<WechatConversationMember> members = conversationMemberMapper.findByConversationId(conversationId);

		List<Long> receivers = new ArrayList<>();

		for (WechatConversationMember member : members) {
			if (!member.getUserId().equals(senderId)) {
				// 更新每个接收者的未读计数
				updateUnreadCountForUser(member.getUserId(), conversationId, message.getId());
				receivers.add(member.getUserId());
			}
		}

		return receivers;
	}

	/**
	 * 更新用户的未读消息计数
	 */
	private void updateUnreadCountForUser(Long userId, Long conversationId, Long messageId) {
		WechatUnreadMessage unreadMessage = unreadMessageMapper.findByUserIdAndConversationId(userId, conversationId)
				.orElseGet(() -> {
					WechatUnreadMessage newUnread = new WechatUnreadMessage();
					newUnread.setUserId(userId);
					newUnread.setConversationId(conversationId);
					newUnread.setUnreadCount(0);
					return newUnread;
				});

		unreadMessage.setUnreadCount(unreadMessage.getUnreadCount() + 1);
		unreadMessage.setLastMessageId(messageId);
		unreadMessage.setUpdateTime(LocalDateTime.now());

		unreadMessageMapper.save(unreadMessage);
	}

	/**
	 * 准备推送数据
	 */
	private Map<String, Object> preparePushData(WechatMessage message, WechatConversation conversation,
			String senderId) {
		// 获取发送者信息
		User sender = commonService.getUserInfo(Long.parseLong(senderId));

		Map<String, Object> pushData = new HashMap<>();
		pushData.put("messageId", message.getId());
		pushData.put("conversationId", message.getConversationId());
		pushData.put("senderId", senderId);
		pushData.put("senderName", sender.getUserName());
		pushData.put("senderAvatar", sender.getAvatar());
		pushData.put("content", message.getContent());
		pushData.put("messageType", message.getMessageType());
		pushData.put("sendTime", message.getSendTime());
		pushData.put("conversationType", conversation.getSessionType());

		return pushData;
	}

	/**
	 * 标记消息为已读
	 */
	public int markMessageAsRead(String conversationId, String userId, Long messageId) {
		try {
			boolean isMember = isMenber(Long.parseLong(conversationId), Long.parseLong(userId));
			// 验证用户和消息权限
			if (!isMember) {
				throw new RuntimeException("用户不是会话成员");
			}

			// 重置未读计数
			unreadMessageMapper.findByUserIdAndConversationId(Long.parseLong(userId), Long.parseLong(conversationId))
					.ifPresent(unreadMessage -> {
						unreadMessage.setUnreadCount(0);
						unreadMessage.setLastMessageId(messageId);
						unreadMessage.setUpdateTime(LocalDateTime.now());
						unreadMessageMapper.save(unreadMessage);
					});

			// 获取当前未读计数
			Integer unreadCount = getUnreadCount(Long.parseLong(userId), Long.parseLong(conversationId));

			// 推送已读回执给其他参与者
			webSocketService.pushMessageReadStatus(conversationId, userId, messageId, unreadCount);

			log.info("消息已读标记成功: conversationId={}, userId={}, messageId={}", conversationId, userId, messageId);

			return 1;

		} catch (Exception e) {
			log.error("标记消息已读失败: conversationId={}, userId={}, messageId={}, error={}", conversationId, userId,
					messageId, e.getMessage(), e);
			return 0;
		}
	}

	/**
	 * 获取会话历史消息
	 */
	public List<WechatMessage> getConversationHistory(String conversationId, String userId ) {
		boolean isMember = isMenber(Long.parseLong(conversationId), Long.parseLong(userId));
		// 验证用户权限
		if (!isMember) {
			throw new RuntimeException("无权访问此会话");
		}

		// 分页查询消息（按时间倒序，最新消息在前）
		Page<User> page = new Page<>(1, Integer.MAX_VALUE);
		return messageMapper.findByConversationIdOrderBySentAtDesc(conversationId, page);
	}

	/**
	 * 获取用户未读消息总数
	 */
	public int getTotalUnreadCount(String userId) {
		return unreadMessageMapper.sumUnreadCountByUserId(userId);
	}

	/**
	 * 获取特定会话的未读消息数
	 */
	public int getUnreadCount(Long userId, Long conversationId) {
		return unreadMessageMapper.findByUserIdAndConversationId(userId, conversationId)
				.map(WechatUnreadMessage::getUnreadCount).orElse(0);
	}

	/**
	 * 撤回消息
	 */
	public boolean recallMessage(Long messageId, Long userId) {
		try {
			WechatMessage message = messageRepository.selectById(messageId);
			// 验证权限：只有发送者可以撤回消息
			if (!message.getFromUser().equals(userId)) {
				throw new RuntimeException("无权撤回此消息");
			}

			// 检查消息时间（例如：只能撤回2分钟内的消息）
			if (message.getSendTime().isBefore(LocalDateTime.now().minusMinutes(2))) {
				throw new RuntimeException("消息已超过可撤回时间");
			}

			// 标记消息为已撤回
			message.setStatus(3); // 3表示已撤回
			messageRepository.insertWechatMessage(message);

			// 推送撤回通知
			webSocketService.pushMessageRecall(message.getConversationId(), messageId, userId);

			log.info("消息撤回成功: messageId={}, userId={}", messageId, userId);
			return true;
		} catch (Exception e) {
			log.error("撤回消息失败: messageId={}, userId={}", messageId, userId, e);
			return false;
		}
	}

	/**
	 * 截断过长的消息内容（用于会话列表显示）
	 */
	private String truncateContent(String content) {
		if (content == null)
			return "";
		return content.length() > 50 ? content.substring(0, 47) + "..." : content;
	}

	/**
	 * 更新会话缓存（性能优化）
	 */
	private void updateConversationCache(WechatConversation conversation) {
		Long cacheKey = conversation.getId();
		conversationCache.put(String.valueOf(cacheKey), new ConversationCache(conversation, LocalDateTime.now()));
	}

	// 获取指定接收者的未读计数
	public Integer getUnreadCount(Long receiverId) {
		// 这里可以根据需要实现具体逻辑
		return 1; // 默认返回1，实际应从数据库查询
	}

	// 会话缓存类
	private static class ConversationCache {
		private final WechatConversation conversation;
		private final LocalDateTime lastUpdated;

		public ConversationCache(WechatConversation conversation, LocalDateTime lastUpdated) {
			this.conversation = conversation;
			this.lastUpdated = lastUpdated;
		}
	}

}